import { downloadFile, getUrlWithBlob } from '@/utils/file'
import { ref, unref } from 'vue'
import dayjs from 'dayjs'

export const useImgWatermark = () => {
  const resBlob = ref()

  const getLuminance = (color: string) => {
    const rgbMatch = color.match(/\d+/g)
    if (!rgbMatch) {
      throw new Error(`Invalid color format: ${color}`)
    }
    const rgb = rgbMatch.map(Number)
    const [r, g, b] = rgb.map((c) => {
      c /= 255
      return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
    })
    return 0.2126 * r + 0.7152 * g + 0.0722 * b
  }

  // 获取与给定颜色对比度高的颜色
  const getContrastColor = (color: string) => {
    const luminance = getLuminance(color)
    return luminance > 0.179 ? 'black' : 'white'
  }

  const getAverageColor = (img: HTMLImageElement) => {
    const canvas = document.createElement('canvas')
    const ctx: CanvasRenderingContext2D = canvas.getContext('2d') as CanvasRenderingContext2D

    canvas.width = img.width
    canvas.height = img.height
    ctx?.drawImage(img, 0, 0)

    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
    let sumRed = 0
    let sumGreen = 0
    let sumBlue = 0
    let count = 0

    for (let i = 0; i < imageData.data.length; i += 4) {
      sumRed += imageData.data[i]
      sumGreen += imageData.data[i + 1]
      sumBlue += imageData.data[i + 2]
      count++
    }

    const avgRed = sumRed / count
    const avgGreen = sumGreen / count
    const avgBlue = sumBlue / count

    return `rgb(${avgRed}, ${avgGreen}, ${avgBlue})`
  }

  // 水印文字的默认样式
  const getDefaultOptions = (img: HTMLImageElement) => {
    // 获取图片的平均颜色
    const averageColor = getAverageColor(img)
    return {
      font: '14px Arial',
      color: getContrastColor(averageColor), // 根据图片平均颜色调整水印颜色
      gap: 100, // 水印间隔
      angle: -15, // 水印旋转角度
    }
  }

  // 绘制明水印
  const fillWatermarkText = ({
    ctx,
    canvas,
    watermarkText,
    settings,
  }: {
    canvas: HTMLCanvasElement
    ctx: CanvasRenderingContext2D
    watermarkText: string
    settings: RecordRaw
  }) => {
    // 计算每个水印的位置
    const textWidth = ctx.measureText(watermarkText).width
    const textHeight = parseInt(settings.font)
    const watermarks: { x: number; y: number }[] = []
    for (let x = 0; x < canvas.width; x += textWidth + settings.gap) {
      for (let y = 0; y < canvas.height; y += textHeight + settings.gap) {
        watermarks.push({ x, y })
      }
    }

    // 绘制每个水印
    ctx.translate(canvas.width / 2, canvas.height / 2)
    ctx.rotate((settings.angle * Math.PI) / 180)
    ctx.translate(-(canvas.width / 2), -(canvas.height / 2))
    const gap = settings.gap ?? 0
    watermarks.forEach((watermark) => {
      const { x, y } = watermark
      ctx.strokeText(watermarkText, x + gap, y + gap)
      ctx.fillText(watermarkText, x + gap, y + gap)
      ctx.strokeText(`${dayjs().format('YYYY-MM-DD HH:mm:ss')}`, x + gap, y + gap + 23)
      ctx.fillText(`${dayjs().format('YYYY-MM-DD HH:mm:ss')}`, x + gap, y + gap + 23)
    })
  }

  // 绘制暗水印
  const embedWatermark = (imageData: ImageData, watermarkText: string, options: RecordRaw) => {
    const defaultOptions = {
      strength: 0.1, // 水印强度
      interval: 10, // 水印间隔
      angle: -20, // 水印旋转角度
      gap: 10,
    }
    const settings = { ...defaultOptions, ...options }

    const canvas = document.createElement('canvas')
    canvas.width = imageData.width
    canvas.height = imageData.height
    const context = canvas.getContext('2d')
    if (context) {
      context.globalAlpha = 0.005
      context.fillStyle = '#000'
      context.putImageData(imageData, 0, 0)
      fillWatermarkText({ ctx: context, canvas, watermarkText, settings })
      return context.getImageData(0, 0, canvas.width, canvas.height)
    }
  }

  /**
   * @description 图片添加水印
   * @param bytes 原始文件的arrarybuffer文件流
   * @param watermarkText 水印文本，可选
   * @param options
   */
  const imgWatermark = (
    bytes: ArrayBuffer,
    watermarkText = 'mm system watermark',
    options = {},
  ) => {
    const blob = new Blob([bytes], { type: 'image/png' })
    const url = URL.createObjectURL(blob)
    const img = new Image()
    img.src = url
    return new Promise((resolve) => {
      img.onload = () => {
        // 释放URL对象
        URL.revokeObjectURL(url)

        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')

        // 设置canvas的宽度和高度为图片的宽度和高度
        canvas.width = img.width
        canvas.height = img.height
        if (ctx) {
          // 在canvas上绘制原图
          ctx.drawImage(img, 0, 0)

          const settings = { ...getDefaultOptions(img), ...options }
          ctx.font = settings.font
          ctx.fillStyle = settings.color
          ctx.textAlign = 'center'
          ctx.textBaseline = 'middle'
          ctx.strokeStyle = settings.color === 'black' ? 'white' : 'black'
          ctx.lineWidth = 1
          fillWatermarkText({ ctx, canvas, watermarkText, settings })

          // 获取图片的ImageData
          const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)

          // 嵌入暗水印
          const watermarkedImageData = embedWatermark(imageData, watermarkText, {})

          // 将处理后的ImageData放回canvas
          if (watermarkedImageData) {
            ctx.putImageData(watermarkedImageData, 0, 0)
          }
          // 将canvas内容转为Blob并执行回调
          canvas.toBlob((blob) => {
            // const url = URL.createObjectURL(blob);
            // decodeWatermark({ url });
            resolve(blob)
            resBlob.value = blob
          })
        }
      }
    })
  }

  const saveImg = (fileName: string) => {
    const url = getUrlWithBlob(unref(resBlob))
    downloadFile(url, fileName)
  }

  return {
    imgWatermark,
    saveImg,
  }
}
